import time

import allure
import pyautogui
import pyperclip
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from loguru import logger

from common.handle_path import screenshot_path


class BasePage:

    # driver每个方法都用，如果直接定位参数，没有办法实现实例方法共享，所以可以定义为实例属性 实现共享
    def __init__(self,driver): # 初始化方法里定义了以参数  到时候实例化对象传参
        """初始化函数 定义driver作为实例属性 实例实例方法共享这个实例属性"""
        self.driver = driver

    # 操作和行为 行为为实例方法
    def wait_element_clickable(self, locator):
        logger.info(f"等待元素{locator}可以点击")
        try:
            web_element = WebDriverWait(self.driver, 8, 0.5).until(EC.element_to_be_clickable(locator))
        except Exception as e:
            logger.error(f"等待元素超时{e}")
            # self.driver.save_screenshot("test.png") # 当发生了异常了 就截图保留现场
            # self.driver.save_screenshot(f"screenshot_{int(time.time() * 1000)}.png")
            # self.driver.save_screenshot(rf"{screenshot_path}\screenshot_{int(time.time() * 1000)}.png")
            allure.attach(self.driver.get_screenshot_as_png(), name=f"{locator}失败用例截图", attachment_type=allure.attachment_type.PNG)
            raise e
        return web_element

    def wait_element_visible(self, locator):
        logger.info(f"等待元素{locator}可见")
        try:
            web_element = WebDriverWait(self.driver, 8, 0.5).until(EC.visibility_of_element_located(locator))
        except Exception as e:
            logger.error(f"等待元素可见异常{e}")
            # self.driver.save_screenshot(rf"{screenshot_path}\screenshot_{int(time.time() * 1000)}.png")
            allure.attach(self.driver.get_screenshot_as_png(), name=f"{locator}失败用例截图", attachment_type=allure.attachment_type.PNG)
            raise e
        return web_element

    def wait_element_presence(self, locator):
        logger.info(f"等待元素{locator}存在")
        try:
            web_element = WebDriverWait(self.driver, 8, 0.5).until(EC.presence_of_element_located(locator))
        except Exception as e:
            logger.error(f"等待元素存在异常{e}")
            # self.driver.save_screenshot(rf"{screenshot_path}\screenshot_{int(time.time() * 1000)}.png")
            allure.attach(self.driver.get_screenshot_as_png(), name=f"{locator}失败用例截图", attachment_type=allure.attachment_type.PNG)
            raise e
        return web_element

    # 1、普通点击操作 --关键字
    def click_element(self,locator):
        logger.info(f"进行普通点击操作：{locator}")
        self.wait_element_clickable(locator).click()

    # 2、鼠标点击操作
    def mouse_click(self,locator):
        logger.info(f"进行鼠标点击操作：{locator}")
        # 先找到元素
        element = self.wait_element_visible(locator)
        # 用鼠标点击
        ActionChains(self.driver).click(element).perform()

    # 3、js点击操作
    def js_click(self,locator):
        logger.info(f"进行js点击操作：{locator}")
        # 先找到元素
        element = self.wait_element_visible(locator)
        # 用js传参点击
        self.driver.execute_script("arguments[0].click()",element)

    # 4、输入数据文本
    def input_text(self,locator,text):
        logger.info(f"进行文本输入操作：{locator}")
        self.wait_element_visible(locator).send_keys(text)

    # 5、获取元素的文本 : 拿到这个文本 返回这个文本
    def get_text(self,locator):
        logger.info(f"进行获取文本操作：{locator}")
        return self.wait_element_visible(locator).text

    # 6、获取元素的属性:拿到这个属性的值 设置为返回值
    def get_attribute(self,locator,attr_name):
        logger.info(f"进行元素属性操作：{locator}")
        return self.wait_element_visible(locator).get_attribute(attr_name)

    # 7、窗口切换
    def switch_window(self,url):
        logger.info(f"切换窗口操作，切换到:{url}")
        # 先拿到所有的窗口句柄
        handles = self.driver.window_handles
        for win in handles:
            if self.driver.current_url == url:  # 判断当前的页面是否为想要的url地址
                break
            else:
                self.driver.switch_to.window(win)  # 如果不是 继续切换

    # 8、移动鼠标
    def move_mouse(self,locator):
        logger.info(f"进行鼠标移动操作：{locator}")
        element = self.wait_element_presence(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    # 9、文件上传
    def file_upload(self,file_path):
        logger.info(f"进行文件上传的操作，上传的文件是：{file_path}")
        # 1、先复制路径
        pyperclip.copy(file_path)
        # 2、粘贴 -- hotkey 通过热键粘贴
        pyautogui.hotkey("ctrl", "v")
        pyautogui.press("enter", presses=2)

    # 10、判断元素是否显示  --  返回：结果是布尔值 显示-True  不显示-False
    def elememnt_display(self,locator):
        logger.info(f"判断元素：{locator}是否存在")
        return self.wait_element_visible(locator).is_displayed()